package tr.edu.metu.is.mega.server.business;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;

import tr.edu.metu.is.mega.common.dto.ActivityType;
import tr.edu.metu.is.mega.common.dto.ReviewerDTO;
import tr.edu.metu.is.mega.common.dto.SubmissionDTO;
import tr.edu.metu.is.mega.common.dto.UserDTO;
import tr.edu.metu.is.mega.server.dao.ActivityDAO;
import tr.edu.metu.is.mega.server.entity.Activity;
import tr.edu.metu.is.mega.server.entity.Announcement;
import tr.edu.metu.is.mega.server.entity.Courseassistant;
import tr.edu.metu.is.mega.server.entity.Coursestudent;
import tr.edu.metu.is.mega.server.entity.Reviewer;
import tr.edu.metu.is.mega.server.entity.Teammember;

/**
 * Mail service manager
 */
public final class MailService {

    private static final String HOST_NAME = "smtp.gmail.com";

    private static final String MAIL_FROM = "mega@ekremkenter.com";

    private static final String MAIL_PWD = "megamail";

    private static final int SMTP_PORT = 587;

    /**
     * Default constructor.
     */
    private MailService() {
    }

    /**
     * Sends user login information via e-mail.
     * 
     * @param emailAddress email address of user
     */
    public static void sendLoginInfo(UserDTO userDTO) {
        StringBuilder mailBuilder = new StringBuilder();
        mailBuilder.append("You requested login information;");
        mailBuilder.append("\n\t Username: ").append(userDTO.getUserName());
        mailBuilder.append("\n\t Password: ").append(userDTO.getPassword());
        sendMail(userDTO.getEmail(), "Login info for MEGA ", mailBuilder.toString());
    }

    public static void welcomeUser(UserDTO userDTO) {
        StringBuilder mailBuilder = new StringBuilder();
        mailBuilder.append("You have granted access to MEGA, you can use information provided below, please change password after login.");
        mailBuilder.append("\n\t Username: ").append(userDTO.getUserName());
        mailBuilder.append("\n\t Password: ").append(userDTO.getPassword());
        sendMail(userDTO.getEmail(), "Welcome to MEGA", mailBuilder.toString());
    }

    public static void sendMail(final String email, final String subject, final String message) {
        if (email.trim().equalsIgnoreCase("dummy@dummy")) {
            return;
        }
        new Thread(new Runnable() {

            @Override
            public void run() {

                Email mail = new SimpleEmail();
                mail.setHostName(HOST_NAME);
                mail.setSmtpPort(SMTP_PORT);
                mail.setAuthenticator(new DefaultAuthenticator(MAIL_FROM, MAIL_PWD));
                mail.setTLS(true);
                try {
                    mail.setFrom(MAIL_FROM);
                    mail.setSubject(subject);
                    mail.setMsg(message);
                    mail.addTo(email);
                    mail.send();
                    System.out.println("MailService.sendMail(...).new Runnable() {...}.run() :" + email + " / " + subject);
                } catch (EmailException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * @param email
     * @param view
     */
    public static void reviewMailer(String email, ReviewerDTO reviewer) {
        StringBuilder mailBuilder = new StringBuilder();
        ActivityDAO dao = new ActivityDAO();
        Activity activity = dao.findById(reviewer.getActivity());
        Activity reviewactivity = dao.findById(reviewer.getReviewActivity());
        mailBuilder.append("Your instructor have assigned your team to review " + reviewer.getTeam().getTeamName() + " for activity "
                + activity.getDescription() + " until " + reviewactivity.getDuedate() + "\n");
        sendMail(email, "MEGA Review Notifier", mailBuilder.toString());
    }

    /**
     * @param email
     * @param view
     */
    public static void activityMailer(Activity activity) {
        StringBuilder mailBuilder = new StringBuilder();
        mailBuilder.append("You have " + activity.getDescription() + " " + ActivityType.findByCode(activity.getSubmissiontype()).getDescription()
                + " with due date " + activity.getDuedate() + " in course " + activity.getCourse().getName() + " (" + activity.getCourse().getCode()
                + ") ");
        for (Coursestudent coursestudent : activity.getCourse().getCoursestudents()) {
            sendMail(coursestudent.getSystemuser().getEmail(), "MEGA Activity Notifier", mailBuilder.toString());
        }
    }

    /**
     * @param view
     */
    public static void announcementMailer(Announcement annonucement) {
        StringBuilder mailBuilder = new StringBuilder();
        mailBuilder.append("New announcement in course " + annonucement.getCourse().getName() + " (" + annonucement.getCourse().getCode()
                + ") \n\n\"" + annonucement.getAnnouncementtext() + "\"");
        for (Coursestudent coursestudent : annonucement.getCourse().getCoursestudents()) {
            sendMail(coursestudent.getSystemuser().getEmail(), "MEGA Annonucement Notifier", mailBuilder.toString());
        }
    }

    /**
     * @param email
     * @param view
     */
    public static void submissionMailer(String email, SubmissionDTO view) {
        StringBuilder mailBuilder = new StringBuilder();
        ActivityDAO dao = new ActivityDAO();
        Activity activity = dao.findById(view.getActivity());
        mailBuilder.append(view.getTeam().getTeamName() + " uploaded " + activity.getDescription() + "\n\n"
                + "Download and make sure you upload your review");
        sendMail(email, "MEGA Review Submission Upload Notifier", mailBuilder.toString());

    }

    /**
     * @param reviewer
     */
    public static void reviewMailer(Reviewer reviewer) {
        StringBuilder mailBuilder = new StringBuilder();
        mailBuilder.append("Team " + reviewer.getTeam().getTeamname() + " has not uploaded any submission for "
                + reviewer.getActivity().getDescription() + " in course " + reviewer.getActivity().getCourse().getName() + " ("
                + reviewer.getActivity().getCourse().getCode() + ") ");
        List<String> emails = new ArrayList<String>();
        for (Teammember coursestudent : reviewer.getReviewerTeam().getTeammembers()) {
            emails.add(coursestudent.getCoursestudent().getSystemuser().getEmail());
        }
        emails.add(reviewer.getActivity().getCourse().getInstructor().getEmail());
        for (Courseassistant courseassistant : reviewer.getActivity().getCourse().getCourseassistants()) {
            emails.add(courseassistant.getSystemuser().getEmail());
        }
        for (String email : emails) {
            sendMail(email, "MEGA Submission Not Uploaded Notifier", mailBuilder.toString());
        }
    }
}
